export default {
  // 返回随机字符串
  randomString: (len: number): string => {
    len = len || 32
    const $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789'
    const maxPos = $chars.length
    let pwd = ''
    for (let i = 0; i < len; i++) {
      pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
    }
    return pwd
  },

  // sessionStorage 封装
  setSessionStorage: (key: string, data: any) => {
    const newData = data
    const storage = window.sessionStorage
    if (typeof newData === 'object' || typeof newData === 'function') {
      storage.setItem(key, JSON.stringify(newData))
    } else {
      storage.setItem(key, newData)
    }
  },
  getSessionStorage: (key: string) => {
    const val = window.sessionStorage.getItem(key)
    try {
      // @ts-ignore
      return JSON.parse(val)
    } catch (error) {
      return val
    } 
  },
  removeSessionStorage (key: string) {
    if (this.getSessionStorage(key)) {
      window.sessionStorage.removeItem(key)
    }
  },

  /**
   * debounce:第一次触发后，进行倒计wait毫秒，如果倒计时过程中有其他触发，则重置倒计时；否则执行。用它来丢弃一些重复的密集操作，直到流量减慢。
   * 使用场景如下
   * mouse move 时减少计算次数
   * input 中输入文字自动发送 ajax 请求进行自动补全
   * ajax 请求合并，不希望短时间内大量的请求被重复发送
   * resize window 重新计算样式或布局
   */
  debounce (fn: any, delay: number) {
    let timer: any
    return () => {
      const args = arguments
      timer && clearTimeout(timer)
      timer = setTimeout(() => {
        fn.apply(this, args)
        timer = null
      }, delay)
    }
  },

  /**
   * hrottle:第一次触发后先执行fn，然后wait ms后再次执行，在单位wait毫秒内的所有重复触发都被抛弃。即如果有连续不断的触发，每wait ms执行fn一次，用在每隔一定间隔执行回调的场景。
   * 使用场景如下
   * resize window 重新计算样式或布局
   * scroll 时触发操作，如随动效果：throttle
   * 对用户输入的验证，不想停止输入再进行验证，而是每n秒进行验证
   */
  throttle (fn: any, delay: number) {
    let last = 0
    return () => {
      const now = Date.now()
      const args = arguments
      if (now - last > delay) {
        fn.apply(this, args)
        last = now
      }
    }
  }
}
